package jmine.tec.utils.parsers;

import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;

/**
 * Implementacao de {@link FilterReader} que quebra a stream em tokens, usando um delimitador passado no construtor
 * 
 * @author takeshi
 */
public class TokenizingReader extends FilterReader {

    private final char delimiter;

    private final boolean includeDelimiter;

    /**
     * C'tor
     * 
     * @param in {@link Reader} o source
     * @param delimiter o char delimitador
     * @param includeDelimiter se true, o delimitador sera incluido nos tokens
     */
    public TokenizingReader(Reader in, char delimiter, boolean includeDelimiter) {
        super(in);
        this.delimiter = delimiter;
        this.includeDelimiter = includeDelimiter;
    }

    /**
     * C'tor que nao inclui o delimitador nos tokens
     * 
     * @param in o {@link Reader}
     * @param delimiter o char delimitador
     */
    public TokenizingReader(Reader in, char delimiter) {
        this(in, delimiter, false);
    }

    /**
     * Devolve o proximo token - a string ateh encontrar um delimitador. Devolve <code>null</code> se o reader chegou ao final
     * 
     * @return String
     * @throws IOException e
     */
    public String nextToken() throws IOException {
        StringBuilder sb = new StringBuilder();
        int read = this.read();
        if (read == -1) {
            return null;
        }
        while (read != -1) {
            if (read == this.delimiter) {
                if (this.includeDelimiter) {
                    sb.append(this.delimiter);
                }
                break;
            }
            sb.append((char) read);
            read = this.read();
        }
        return sb.toString();
    }

    /**
     * @return the delimiter
     */
    public char getDelimiter() {
        return this.delimiter;
    }

    /**
     * @return the includeDelimiter
     */
    public boolean isIncludeDelimiter() {
        return this.includeDelimiter;
    }

}
